package co.edu.usbcali.correspondencia.presentation.backingBeans;

import co.edu.usbcali.correspondencia.exceptions.*;
import co.edu.usbcali.correspondencia.modelo.*;
import co.edu.usbcali.correspondencia.modelo.dto.VehiculoDTO;
import co.edu.usbcali.correspondencia.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.correspondencia.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;


/**
*
*
* @author Zathura Code Generator http://code.google.com/p/zathura
*
*/
public class VehiculoView extends DataSource implements Renderable,
    DisposableBean {
    private HtmlInputText txtVeiColor;
    private HtmlInputText txtVeiMarca;
    private HtmlInputText txtEstCodigo_Estado;
    private HtmlInputText txtPerCedula_Persona;
    private HtmlInputText txtTpvCodigo_TipoVehiculo;
    private HtmlInputText txtVeiCodigo;
    private SelectInputDate txtVeiAno;
    private HtmlCommandButton btnSave;
    private HtmlCommandButton btnModify;
    private HtmlCommandButton btnDelete;
    private HtmlCommandButton btnClear;
    private boolean renderDataTable;
    private boolean flag = true;
    private RenderManager renderManager;
    private PersistentFacesState state = PersistentFacesState.getInstance();
    private List<Vehiculo> vehiculo;
    private List<VehiculoDTO> vehiculoDTO;

    public VehiculoView() {
        super("");
    }

    public String action_clear() {
        txtVeiColor.setValue(null);
        txtVeiColor.setDisabled(true);
        txtVeiMarca.setValue(null);
        txtVeiMarca.setDisabled(true);
        txtEstCodigo_Estado.setValue(null);
        txtEstCodigo_Estado.setDisabled(true);
        txtPerCedula_Persona.setValue(null);
        txtPerCedula_Persona.setDisabled(true);
        txtTpvCodigo_TipoVehiculo.setValue(null);
        txtTpvCodigo_TipoVehiculo.setDisabled(true);
        txtVeiAno.setValue(null);
        txtVeiAno.setDisabled(true);
        txtVeiCodigo.setValue(null);
        txtVeiCodigo.setDisabled(false);
        btnSave.setDisabled(true);
        btnDelete.setDisabled(true);
        btnModify.setDisabled(true);
        btnClear.setDisabled(false);

        return "";
    }

    public void listener_txtId(ValueChangeEvent event) {
        if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
            Vehiculo entity = null;

            try {
                String veiCodigo = new String(txtVeiCodigo.getValue().toString());
                entity = BusinessDelegatorView.getVehiculo(veiCodigo);
            } catch (Exception e) {
                // TODO: handle exception
            }

            if (entity == null) {
                txtVeiColor.setDisabled(false);
                txtVeiMarca.setDisabled(false);
                txtEstCodigo_Estado.setDisabled(false);
                txtPerCedula_Persona.setDisabled(false);
                txtTpvCodigo_TipoVehiculo.setDisabled(false);
                txtVeiAno.setDisabled(false);
                txtVeiCodigo.setDisabled(false);
                btnSave.setDisabled(false);
                btnDelete.setDisabled(true);
                btnModify.setDisabled(true);
                btnClear.setDisabled(false);
            } else {
                txtVeiAno.setValue(entity.getVeiAno());
                txtVeiAno.setDisabled(false);
                txtVeiColor.setValue(entity.getVeiColor());
                txtVeiColor.setDisabled(false);
                txtVeiMarca.setValue(entity.getVeiMarca());
                txtVeiMarca.setDisabled(false);
                txtEstCodigo_Estado.setValue(entity.getEstado().getEstCodigo());
                txtEstCodigo_Estado.setDisabled(false);
                txtPerCedula_Persona.setValue(entity.getPersona().getPerCedula());
                txtPerCedula_Persona.setDisabled(false);
                txtTpvCodigo_TipoVehiculo.setValue(entity.getTipoVehiculo()
                                                         .getTpvCodigo());
                txtTpvCodigo_TipoVehiculo.setDisabled(false);
                txtVeiCodigo.setValue(entity.getVeiCodigo());
                txtVeiCodigo.setDisabled(true);
                btnSave.setDisabled(true);
                btnDelete.setDisabled(false);
                btnModify.setDisabled(false);
                btnClear.setDisabled(false);
            }
        }
    }

    public String action_save() {
        try {
            BusinessDelegatorView.saveVehiculo(FacesUtils.checkDate(txtVeiAno),
                FacesUtils.checkString(txtVeiCodigo),
                FacesUtils.checkString(txtVeiColor),
                FacesUtils.checkString(txtVeiMarca),
                FacesUtils.checkString(txtEstCodigo_Estado),
                FacesUtils.checkString(txtPerCedula_Persona),
                FacesUtils.checkString(txtTpvCodigo_TipoVehiculo));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_delete() {
        try {
            BusinessDelegatorView.deleteVehiculo(FacesUtils.checkString(
                    txtVeiCodigo));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modify() {
        try {
            BusinessDelegatorView.updateVehiculo(FacesUtils.checkDate(txtVeiAno),
                FacesUtils.checkString(txtVeiCodigo),
                FacesUtils.checkString(txtVeiColor),
                FacesUtils.checkString(txtVeiMarca),
                FacesUtils.checkString(txtEstCodigo_Estado),
                FacesUtils.checkString(txtPerCedula_Persona),
                FacesUtils.checkString(txtTpvCodigo_TipoVehiculo));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modifyWitDTO(Date veiAno, String veiCodigo,
        String veiColor, String veiMarca, String estCodigo_Estado,
        String perCedula_Persona, String tpvCodigo_TipoVehiculo)
        throws Exception {
        try {
            BusinessDelegatorView.updateVehiculo(veiAno, veiCodigo, veiColor,
                veiMarca, estCodigo_Estado, perCedula_Persona,
                tpvCodigo_TipoVehiculo);
            renderManager.getOnDemandRenderer("VehiculoView").requestRender();
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
        } catch (Exception e) {
            //renderManager.getOnDemandRenderer("VehiculoView").requestRender();
            FacesUtils.addErrorMessage(e.getMessage());
            throw e;
        }

        return "";
    }

    public List<Vehiculo> getVehiculo() {
        if (flag) {
            try {
                vehiculo = BusinessDelegatorView.getVehiculo();
                flag = false;
            } catch (Exception e) {
                flag = true;
                FacesUtils.addErrorMessage(e.getMessage());
            }
        }

        return vehiculo;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setVehiculo(List<Vehiculo> vehiculo) {
        this.vehiculo = vehiculo;
    }

    public boolean isRenderDataTable() {
        try {
            if (flag) {
                if (BusinessDelegatorView.findTotalNumberVehiculo() > 0) {
                    renderDataTable = true;
                } else {
                    renderDataTable = false;
                }
            }

            flag = false;
        } catch (Exception e) {
            renderDataTable = false;
            e.printStackTrace();
        }

        return renderDataTable;
    }

    public DataModel getData() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModel(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<Vehiculo> getDataPage(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberVehiculo = 0;

        try {
            totalNumberVehiculo = BusinessDelegatorView.findTotalNumberVehiculo()
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberVehiculo) {
            endIndex = totalNumberVehiculo;
        }

        try {
            vehiculo = BusinessDelegatorView.findPageVehiculo(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            // Remove this Renderable from the existing render groups.
            //leaveRenderGroups();        			
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        //joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<Vehiculo>(totalNumberVehiculo, startRow, vehiculo);
    }

    public DataModel getDataDTO() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModelDTO(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<VehiculoDTO> getDataPageDTO(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberVehiculo = 0;

        try {
            totalNumberVehiculo = BusinessDelegatorView.findTotalNumberVehiculo()
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberVehiculo) {
            endIndex = totalNumberVehiculo;
        }

        try {
            vehiculo = BusinessDelegatorView.findPageVehiculo(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            if (Utilities.validationsList(vehiculo)) {
                vehiculoDTO = new ArrayList<VehiculoDTO>();

                for (Vehiculo vehiculoTmp : vehiculo) {
                    VehiculoDTO vehiculoDTO2 = new VehiculoDTO();
                    vehiculoDTO2.setVeiCodigo(vehiculoTmp.getVeiCodigo()
                                                         .toString());
                    vehiculoDTO2.setVeiAno(vehiculoTmp.getVeiAno());
                    vehiculoDTO2.setVeiColor((vehiculoTmp.getVeiColor() != null)
                        ? vehiculoTmp.getVeiColor().toString() : null);
                    vehiculoDTO2.setVeiMarca((vehiculoTmp.getVeiMarca() != null)
                        ? vehiculoTmp.getVeiMarca().toString() : null);
                    vehiculoDTO2.setEstCodigo_Estado((vehiculoTmp.getEstado()
                                                                 .getEstCodigo() != null)
                        ? vehiculoTmp.getEstado().getEstCodigo().toString() : null);
                    vehiculoDTO2.setPerCedula_Persona((vehiculoTmp.getPersona()
                                                                  .getPerCedula() != null)
                        ? vehiculoTmp.getPersona().getPerCedula().toString()
                        : null);
                    vehiculoDTO2.setTpvCodigo_TipoVehiculo((vehiculoTmp.getTipoVehiculo()
                                                                       .getTpvCodigo() != null)
                        ? vehiculoTmp.getTipoVehiculo().getTpvCodigo().toString()
                        : null);
                    vehiculoDTO2.setVehiculo(vehiculoTmp);
                    vehiculoDTO2.setVehiculoView(this);
                    vehiculoDTO.add(vehiculoDTO2);
                }
            }

            // Remove this Renderable from the existing render groups.
            leaveRenderGroups();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<VehiculoDTO>(totalNumberVehiculo, startRow,
            vehiculoDTO);
    }

    protected boolean isDefaultAscending(String sortColumn) {
        return true;
    }

    /**
    * This method is called when a render call is made from the server. Render
    * calls are only made to views containing an updated record. The data is
    * marked as dirty to trigger a fetch of the updated record from the
    * database before rendering takes place.
    */
    public PersistentFacesState getState() {
        onePageDataModel.setDirtyData();

        return state;
    }

    /**
    * This method is called from faces-config.xml with each new session.
    */
    public void setRenderManager(RenderManager renderManager) {
        this.renderManager = renderManager;
    }

    public void renderingException(RenderingException arg0) {
        if (arg0 instanceof TransientRenderingException) {
        } else if (arg0 instanceof FatalRenderingException) {
            // Remove from existing Customer render groups.
            leaveRenderGroups();
        }
    }

    /**
    * Remove this Renderable from existing uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void leaveRenderGroups() {
        if (Utilities.validationsList(vehiculoDTO)) {
            for (VehiculoDTO vehiculoTmp : vehiculoDTO) {
                renderManager.getOnDemandRenderer("VehiculoView").remove(this);
            }
        }
    }

    /**
    * Add this Renderable to the new uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void joinRenderGroups() {
        if (Utilities.validationsList(vehiculoDTO)) {
            for (VehiculoDTO vehiculoTmp : vehiculoDTO) {
                renderManager.getOnDemandRenderer("VehiculoView").add(this);
            }
        }
    }

    public void dispose() throws Exception {
    }

    public RenderManager getRenderManager() {
        return renderManager;
    }

    public void setState(PersistentFacesState state) {
        this.state = state;
    }

    public HtmlInputText getTxtVeiColor() {
        return txtVeiColor;
    }

    public void setTxtVeiColor(HtmlInputText txtVeiColor) {
        this.txtVeiColor = txtVeiColor;
    }

    public HtmlInputText getTxtVeiMarca() {
        return txtVeiMarca;
    }

    public void setTxtVeiMarca(HtmlInputText txtVeiMarca) {
        this.txtVeiMarca = txtVeiMarca;
    }

    public HtmlInputText getTxtEstCodigo_Estado() {
        return txtEstCodigo_Estado;
    }

    public void setTxtEstCodigo_Estado(HtmlInputText txtEstCodigo_Estado) {
        this.txtEstCodigo_Estado = txtEstCodigo_Estado;
    }

    public HtmlInputText getTxtPerCedula_Persona() {
        return txtPerCedula_Persona;
    }

    public void setTxtPerCedula_Persona(HtmlInputText txtPerCedula_Persona) {
        this.txtPerCedula_Persona = txtPerCedula_Persona;
    }

    public HtmlInputText getTxtTpvCodigo_TipoVehiculo() {
        return txtTpvCodigo_TipoVehiculo;
    }

    public void setTxtTpvCodigo_TipoVehiculo(
        HtmlInputText txtTpvCodigo_TipoVehiculo) {
        this.txtTpvCodigo_TipoVehiculo = txtTpvCodigo_TipoVehiculo;
    }

    public SelectInputDate getTxtVeiAno() {
        return txtVeiAno;
    }

    public void setTxtVeiAno(SelectInputDate txtVeiAno) {
        this.txtVeiAno = txtVeiAno;
    }

    public HtmlInputText getTxtVeiCodigo() {
        return txtVeiCodigo;
    }

    public void setTxtVeiCodigo(HtmlInputText txtVeiCodigo) {
        this.txtVeiCodigo = txtVeiCodigo;
    }

    public HtmlCommandButton getBtnSave() {
        return btnSave;
    }

    public void setBtnSave(HtmlCommandButton btnSave) {
        this.btnSave = btnSave;
    }

    public HtmlCommandButton getBtnModify() {
        return btnModify;
    }

    public void setBtnModify(HtmlCommandButton btnModify) {
        this.btnModify = btnModify;
    }

    public HtmlCommandButton getBtnDelete() {
        return btnDelete;
    }

    public void setBtnDelete(HtmlCommandButton btnDelete) {
        this.btnDelete = btnDelete;
    }

    public HtmlCommandButton getBtnClear() {
        return btnClear;
    }

    public void setBtnClear(HtmlCommandButton btnClear) {
        this.btnClear = btnClear;
    }

    public void setRenderDataTable(boolean renderDataTable) {
        this.renderDataTable = renderDataTable;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<VehiculoDTO> getVehiculoDTO() {
        return vehiculoDTO;
    }

    public void setVehiculoDTO(List<VehiculoDTO> vehiculoDTO) {
        this.vehiculoDTO = vehiculoDTO;
    }

    public TimeZone getTimeZone() {
        return java.util.TimeZone.getDefault();
    }

    /**
    * A special type of JSF DataModel to allow a datatable and datapaginator
    * to page through a large set of data without having to hold the entire
    * set of data in memory at once.
    * Any time a managed bean wants to avoid holding an entire dataset,
    * the managed bean declares this inner class which extends PagedListDataModel
    * and implements the fetchData method. fetchData is called
    * as needed when the table requires data that isn't available in the
    * current data page held by this object.
    * This requires the managed bean (and in general the business
    * method that the managed bean uses) to provide the data wrapped in
    * a DataPage object that provides info on the full size of the dataset.
    */
    private class LocalDataModel extends PagedListDataModel {
        public LocalDataModel(int pageSize) {
            super(pageSize);
        }

        public DataPage<Vehiculo> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPage(startRow, pageSize);
        }
    }

    private class LocalDataModelDTO extends PagedListDataModel {
        public LocalDataModelDTO(int pageSize) {
            super(pageSize);
        }

        public DataPage<VehiculoDTO> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPageDTO(startRow, pageSize);
        }
    }
}
